﻿using System;
using System.Linq;
using System.Collections;

/*
Reverse Bit permissions i.e 0 =have permission, 1 = no permission
Column Type is tinyint i.e 1 byte = 8 bits
1st bit = 1st bit from extreme right

0 - Tab - Edit Name          (1111111111111110)
1 - Tab - Share              (1111111111111101)
2 - Tab - Delete             (1111111111111011)
3 - Tab - Add Widgets        (1111111111110111)
4 - Tab - Change Layout      (1111111111101111)
5 - Tab - Change Theme       (1111111111011111)
6 - Widget - Edit Properties (1111111110111111)
7 - Widget - Reorder         (1111111101111111)
8 - Widget - Delete          (1111111011111111)
9 - Widget - Edit Title      (1111110111111111)
31 - Read     (01111111111111111)
int.MinValue i.e 11111...111 - No Rights
using minvalue because in binary, negation is defined by the first bit
*/

public enum TabAccessLevel
{
   Owner = 0,
   Tab_EditName = 1,
   Tab_Share = 2,
   Tab_Delete = 3,
   Tab_AddWidgets = 4,
   Tab_ChangeLayout = 5,
   Tab_ChangeTheme = 6,
   Widget_Edit = 7,
   Widget_Reorder = 8,
   Widget_Delete = 9,
   Widget_EditTitle = 10,
   Tab_Read = 11,
   None = Int32.MinValue
}

public class TabAccessLevelFunctions
{
   public TabAccessLevelFunctions()
   {
   }

   public static bool UserHasPermission(string UserID, int TabID, TabAccessLevel lvl)
   {
      if (TabID < 1 || UserID.Length < 1)
         return false;

      using (var db = DataLayer.DatabaseHelper.GetDashboardData())
      {
         var Levels = from p in db.UserTabs
                      where p.aspnet_User.UserName == UserID && p.TabId == TabID
                      select p.AccessLevel;

         bool hasPermission = false;

         foreach (var Level in Levels)
         {
            if (UserHasPermission(Level, lvl))
            {
               hasPermission = true;
               break;
            }
         }
         return hasPermission;
      }
   }

   public static bool UserHasPermission(Guid UserID, int TabID, TabAccessLevel lvl)
   {
      if (TabID < 1 || UserID == Guid.Empty)
         return false;

      using (var db = DataLayer.DatabaseHelper.GetDashboardData())
      {
         var Levels = from p in db.UserTabs
                     where p.UserID == UserID && p.TabId == TabID
                     select p.AccessLevel;

         bool hasPermission = false;

         foreach (var Level in Levels)
         {
            if (UserHasPermission(Level, lvl))
            {
               hasPermission = true;
               break;
            }
         }
         return hasPermission;
      }
   }

   public static int GeneratePermissionLevel(bool Owner, bool Tab_Read, bool Tab_EditName, bool Tab_Share, bool Tab_Delete, bool Tab_AddWidgets, bool Tab_ChangeLayout, bool Tab_ChangeTheme, bool Widget_Edit, bool Widget_Reorder, bool Widget_Delete, bool Widget_EditTitle)
   {
      if (Owner)
         return 0;
      else
      {
         string PermissionLevel = (Tab_Read ? "0" : "1") +
                                 "111111111111111111111" +
                                  (Widget_EditTitle ? "0" : "1") +
                                  (Widget_Delete ? "0" : "1") +
                                  (Widget_Reorder ? "0" : "1") +
                                  (Widget_Edit ? "0" : "1") +
                                  (Tab_ChangeTheme ? "0" : "1") +
                                  (Tab_ChangeLayout ? "0" : "1") +
                                  (Tab_AddWidgets ? "0" : "1") +
                                  (Tab_Delete ? "0" : "1") +
                                  (Tab_Share ? "0" : "1") +
                                  (Tab_EditName ? "0" : "1");
         //Response.Write(PermissionLevel + "<br>");
         return Convert.ToInt32(PermissionLevel, 2);
      }
   }
   public static TabAccessLevel[] GetAccessLevels(int lvl)
   {
      BitArray b = new BitArray(new int[1] { lvl });
      ArrayList result = new ArrayList();
      if (lvl == 0)
      {
         //if lvl ===0 that means is owner of tab, so can give everything
         result.Add(TabAccessLevel.Owner);
      }
      else if (lvl == Int32.MinValue)
      {
         result.Add(TabAccessLevel.None);
      }
      else
      {
         if (!b[31])
         {
            result.Add(TabAccessLevel.Tab_Read);
         }

         if (!b[9])
         {
            result.Add(TabAccessLevel.Widget_EditTitle);
         }

         if (!b[8])
         {
            result.Add(TabAccessLevel.Widget_Delete);
         }

         if (!b[7])
         {
            result.Add(TabAccessLevel.Widget_Reorder);
         }

         if (!b[6])
         {
            result.Add(TabAccessLevel.Widget_Edit);
         }

         if (!b[5])
         {
            result.Add(TabAccessLevel.Tab_ChangeTheme);
         }

         if (!b[4])
         {
            result.Add(TabAccessLevel.Tab_ChangeLayout);
         }

         if (!b[3])
         {
            result.Add(TabAccessLevel.Tab_AddWidgets);
         }

         if (!b[2])
         {
            result.Add(TabAccessLevel.Tab_Delete);
         }

         if (!b[1])
         {
            result.Add(TabAccessLevel.Tab_Share);
         }

         if (!b[0])
         {
            result.Add(TabAccessLevel.Tab_EditName);
         }
      }
      return (TabAccessLevel[])result.ToArray(typeof(TabAccessLevel));
   }

   public static TabAccessLevel[] UpdateAccessLevels(TabAccessLevel[] lvls, int lvl)
   {
      TabAccessLevel[] newlvls = GetAccessLevels(lvl);

      ArrayList result = new ArrayList();

      foreach (TabAccessLevel xlvl in lvls)
      {
         if (xlvl == TabAccessLevel.Owner)
         {
            result.Clear();
            result.Add(xlvl);
            return (TabAccessLevel[])result.ToArray(typeof(TabAccessLevel));
         }
         else
         {
            result.Add(xlvl);
         }
      }

      foreach (TabAccessLevel xlvl in newlvls)
         if (result.IndexOf(xlvl) < 1)
         {
            if (xlvl == TabAccessLevel.Owner)
            {
               result.Clear();
               result.Add(xlvl);
               return (TabAccessLevel[])result.ToArray(typeof(TabAccessLevel));
            }
            else
            {
               result.Add(xlvl);
            }
         }

      return (TabAccessLevel[])result.ToArray(typeof(TabAccessLevel));
   }

   public static bool UserHasPermission(int lvl, TabAccessLevel RequiredLvl)
   {
      return UserHasPermission(GetAccessLevels(lvl), RequiredLvl);
   }
   public static bool UserHasPermission(TabAccessLevel[] lvls, TabAccessLevel RequiredLvl)
   {
      foreach (TabAccessLevel t in lvls)
      {
         if (t == RequiredLvl || t == TabAccessLevel.Owner)
            return true;
      }
      return false;
   }

}